package com.mingqijia.gassafety.webserver.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.gap.basic.exception.BizException;
import com.mingqijia.gassafety.authority.api.resp.config.DictionaryItemRespDTO;
import com.mingqijia.gassafety.db.entity.Dictionary;
import com.mingqijia.gassafety.db.entity.FuncArea;
import com.mingqijia.gassafety.db.mapper.DictionaryMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mingqijia.gassafety.db.mapper.FuncAreaMapper;
import com.mingqijia.gassafety.shared.dto.UserFuncCodePermissionDTO;
import com.mingqijia.gassafety.shared.utils.ApplicationUtils;
import com.mingqijia.gassafety.webserver.response.FuncAreaZoomResponse;
import com.mingqijia.gassafety.webserver.service.DictionaryService;
import com.mingqijia.gassafety.webserver.service.UserPermissionService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 字典项 服务实现类
 * </p>
 *
 * @author zhangfei
 * @since 2022-02-23
 */
@Service
@Slf4j
public class DictionaryServiceImpl extends ServiceImpl<DictionaryMapper, Dictionary> implements DictionaryService {

    @Autowired
    DictionaryMapper dictionaryMapper;

    @Resource
    UserPermissionService userPermissionService;

    @Resource
    FuncAreaMapper funcAreaMapper;

    @Override
    public Dictionary selectValueByAlias(String mbpOrgCode) {
        LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(Dictionary::getDictCode,"mbp_org_mapping")
        .eq(Dictionary::getIsDeleted,0).likeRight(Dictionary::getAlias,"|"+mbpOrgCode+"|");
        List<Dictionary> dictionaries = dictionaryMapper.selectList(queryWrapper);
        log.info("selectValueByAlias-dictionaries:{}", JSONObject.toJSONString(dictionaries));
        if (CollectionUtil.isEmpty(dictionaries)) throw new BizException("映射不到相关组织信息:"+mbpOrgCode);
        return dictionaries.get(0);
    }

    @Override
    public String selectNewAsstSpMapping(String spId) {
        LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(Dictionary::getDictCode,"new_asst_sp_mapping")
                .eq(Dictionary::getIsDeleted,0)
                .eq(Dictionary::getAlias,spId);
        List<Dictionary> dictionaries = dictionaryMapper.selectList(queryWrapper);
        log.info("selectNewAsstSpMapping-dictionaries:{}", JSONObject.toJSONString(dictionaries));

        if (CollectionUtil.isEmpty(dictionaries)){//没有映射的spId直接使用自身
            return spId;
        }
        return dictionaries.get(0).getValue();
    }

    @Override
    public List<String> selectNewAsstSpMappingSpIds(String spId) {
        LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(Dictionary::getDictCode,"new_asst_sp_mapping")
                .eq(Dictionary::getIsDeleted,0)
                .eq(Dictionary::getValue,spId);
        List<Dictionary> dictionaries = dictionaryMapper.selectList(queryWrapper);
        log.info("selectNewAsstSpMappingSpIds-dictionaries:{}", JSONObject.toJSONString(dictionaries));

        if (CollectionUtil.isEmpty(dictionaries)){//没有映射的spId直接使用自身
            return new ArrayList<>();
        }
        return dictionaries.stream().map(Dictionary::getAlias).collect(Collectors.toList());
    }

    @Override
    public String selectZJSpMapping(String spId) {
        LambdaQueryWrapper<Dictionary> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.or().eq(Dictionary::getDictCode,"zj_dtu_sp_mapping")
                .eq(Dictionary::getIsDeleted,0)
                .eq(Dictionary::getAlias,spId);
        List<Dictionary> dictionaries = dictionaryMapper.selectList(queryWrapper);
        log.info("selectZJSpMapping-dictionaries:{}", JSONObject.toJSONString(dictionaries));

        if (CollectionUtil.isEmpty(dictionaries)){//没有映射的spId直接使用自身
            return spId;
        }
        return dictionaries.get(0).getValue();
    }

    @Override
    public String getChannel() {
        String spId = ApplicationUtils.getWorkingSpId();
        LambdaQueryWrapper<Dictionary> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dictionary::getDictCode, "Call_channel_configuration").eq(Dictionary::getIsDeleted, 0)
                .eq(Dictionary::getValue, spId);
        List<Dictionary> dictionaries = dictionaryMapper.selectList(lqw);
        log.info("getChannel-dictionaries:{}", JSONObject.toJSONString(dictionaries));
        if (CollectionUtil.isEmpty(dictionaries)) {
            return null;
        }else{
            return dictionaries.get(0).getDescription();

        }
    }

    @Override
    public String getChannel(String spId) {
        LambdaQueryWrapper<Dictionary> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dictionary::getDictCode, "Call_channel_configuration").eq(Dictionary::getIsDeleted, 0)
                .eq(Dictionary::getValue, spId);
        List<Dictionary> dictionaries = dictionaryMapper.selectList(lqw);
        log.info("getChannel-dictionaries:{}", JSONObject.toJSONString(dictionaries));
        if (CollectionUtil.isEmpty(dictionaries)) {
            return null;
        }else{
            return dictionaries.get(0).getDescription();

        }
    }

    /**
     * 获取 value 对应的 alias
     *
     */
    @Override
    public String getName(List<DictionaryItemRespDTO> list, String  value) {
        if( !CollectionUtils.isEmpty(list)){
            List<DictionaryItemRespDTO> respDTOS = list.stream()
                    .filter(dict -> dict.getValue().equals(value)).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(respDTOS)){
                return respDTOS.get(0).getName();
            }
        }
        return null;
    }

    @Override
    public Map<String,String> getFuncAreaZoom(String spId) {
        Map<String,String> zoomMap = new HashMap<>();
        zoomMap.put("street","12-15");
        zoomMap.put("district","10-12");
        zoomMap.put("city","0-10");
        zoomMap.put("mapDefaultZoom","9");
        zoomMap.put("mapBreakPointZoom","15");
        try {
            LambdaQueryWrapper<Dictionary> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Dictionary::getDictCode, "FunctionalArea_level_config")
                    .eq(Dictionary::getIsDeleted, 0)
                    .eq(Dictionary::getSpId, spId);
            List<Dictionary> dictionaries = dictionaryMapper.selectList(lqw);
            log.info("FunctionalArea_level_config:{}", JSONObject.toJSONString(dictionaries));
            if (CollectionUtil.isEmpty(dictionaries)) {
                return getFunAreaDefaultZoom(zoomMap);
            }
            Map<String, String> dictMap = dictionaries.stream().collect(
                    Collectors.toMap(Dictionary::getAlias, Dictionary::getValue)
            );
            String funcAreaKey = "FunctionalArea_01";
            String streetKey = "Street_02";
            String tradeAreaKey = "TradeArea_03";

            if (!dictMap.containsKey(funcAreaKey) && !dictMap.containsKey(streetKey) && !dictMap.containsKey(tradeAreaKey)) {
                log.info("功能区，街道，商圈层级都没有配置，使用默认");
                return getFunAreaDefaultZoom(zoomMap);
            }

            String funcAreaLevel = dictMap.get(funcAreaKey);
            String streetLevel = dictMap.get(streetKey);
            String tradeAreaLevel = dictMap.get(tradeAreaKey);
            if ("0".equals(funcAreaLevel) && "0".equals(streetLevel) && "0".equals(tradeAreaLevel)){//地图无需聚合展示
                zoomMap.put("street","0");
                zoomMap.put("district","0");
                zoomMap.put("city","0");
                zoomMap.put("mapDefaultZoom","0");
                zoomMap.put("mapBreakPointZoom","0");
                return zoomMap;
            }
            List<String> levelArr = new ArrayList<>();
            if (!StringUtils.isEmpty(funcAreaLevel) && funcAreaLevel.split("_").length==2) {
                levelArr.add(funcAreaLevel);
                zoomMap.put("city", funcAreaLevel.replace("_", "-"));
            }else{
                zoomMap.put("city", "");
            }
            if (!StringUtils.isEmpty(streetLevel) && streetLevel.split("_").length==2) {
                levelArr.add(streetLevel);
                zoomMap.put("district", streetLevel.replace("_", "-"));
            }else{
                zoomMap.put("district", "");
            }
            if (!StringUtils.isEmpty(tradeAreaLevel) && tradeAreaLevel.split("_").length==2) {
                levelArr.add(tradeAreaLevel);
                zoomMap.put("street", tradeAreaLevel.replace("_", "-"));
            }else{
                zoomMap.put("street", "");
            }
            if (!levelArr.isEmpty()){
                String minLevel = levelArr.get(0);
                String maxLevel = levelArr.get(levelArr.size()-1);
                int dp = Math.max(Integer.parseInt(minLevel.split("_")[1])-1,0);
                int bp = Integer.parseInt(maxLevel.split("_")[1]);
                zoomMap.put("mapDefaultZoom",String.valueOf(dp));
                zoomMap.put("mapBreakPointZoom",String.valueOf(bp));
            }
        }catch(Exception e){
            log.error("getFuncAreaZoom:",e);
        }
        log.info("当前zoom层级配置:{}",JSONObject.toJSONString(zoomMap));
        return getFunAreaDefaultZoom(zoomMap);
    }

    /**
     * 获取功能区默认层级
     * @param zoomMap
     * @return
     */
    private Map<String,String> getFunAreaDefaultZoom(Map<String,String> zoomMap){
        try {
            UserFuncCodePermissionDTO userFuncCodePermission = userPermissionService.getUserDepartPermission(
                    ApplicationUtils.getHeaderSpId(),
                    ApplicationUtils.getUserId()
            );
            if(null!=userFuncCodePermission && null!=userFuncCodePermission.getFuncCodes() && !userFuncCodePermission.getFuncIds().isEmpty()){
                List<FuncArea> funcAreas = funcAreaMapper.selectBatchIds(userFuncCodePermission.getFuncIds());
                boolean hasCity = false;
                boolean hasDistrict = false;
                boolean hasStreet = false;
                for (FuncArea item:funcAreas){
                    if (1==item.getLevel()){
                        hasCity = true;
                    }else if(2==item.getLevel()){
                        hasDistrict = true;
                    }else if(3==item.getLevel()){
                        hasStreet = true;
                    }
                }
                String defaultZoomRange = "0-10";
                if( hasCity ){
                    defaultZoomRange = zoomMap.get("city");
                }else if( hasDistrict ){
                    defaultZoomRange = zoomMap.get("district");
                }else if(hasStreet){
                    defaultZoomRange = zoomMap.get("street");
                }
                if (!StringUtils.isEmpty(defaultZoomRange) && defaultZoomRange.split("-").length==2){
                    int dp = Math.max(Integer.parseInt(defaultZoomRange.split("-")[1])-1,0);
                    zoomMap.put("mapDefaultZoom",String.valueOf(dp));
                }
            }
        }catch (Exception e){
            log.error("getTargetFunArea error",e);
        }
        return zoomMap;
    }

    @Override
    public Map<String, String> getFuncAreaZoomAggregation(String spId) {
        Map<String,String> zoomMap = new HashMap<>();
        try {
            LambdaQueryWrapper<Dictionary> lqw = new LambdaQueryWrapper<>();
            lqw.eq(Dictionary::getDictCode, "FunctionalArea_level_config")
                    .eq(Dictionary::getIsDeleted, 0)
                    .eq(Dictionary::getSpId, spId);
            List<Dictionary> dictionaries = dictionaryMapper.selectList(lqw);
            log.info("FunctionalArea_level_config:{}", JSONObject.toJSONString(dictionaries));
            if (CollectionUtil.isEmpty(dictionaries) || dictionaries.size() != 3) {
                return zoomMap;
            }
            Map<String, String> dictMap = dictionaries.stream().collect(
                    Collectors.toMap(Dictionary::getAlias, Dictionary::getValue)
            );
            String funcAreaKey = "FunctionalArea_01";
            String streetKey = "Street_02";
            String tradeAreaKey = "TradeArea_03";
            if (!dictMap.containsKey(funcAreaKey) || !dictMap.containsKey(streetKey) || !dictMap.containsKey(tradeAreaKey)) {
                log.info("功能区，街道，商圈层级配置缺失，使用默认");
                return zoomMap;
            }

            String funcAreaLevel = dictMap.get(funcAreaKey);
            String streetLevel = dictMap.get(streetKey);
            String tradeAreaLevel = dictMap.get(tradeAreaKey);
            if ("0".equals(funcAreaLevel) && "0".equals(streetLevel) && "0".equals(tradeAreaLevel)){//地图无需聚合展示
                zoomMap.put("street","0");
                zoomMap.put("district","0");
                zoomMap.put("city","0");
                return zoomMap;
            }

            String[] funcAreaLevelArr = funcAreaLevel.split("_");
            String[] streetLevelArr = streetLevel.split("_");
            String[] tradeAreaLevelArr = tradeAreaLevel.split("_");
            if (funcAreaLevelArr.length == 2 && streetLevelArr.length == 2 && tradeAreaLevelArr.length == 2
                    && funcAreaLevelArr[1].equals(streetLevelArr[0]) && streetLevelArr[1].equals(tradeAreaLevelArr[0])) {
                zoomMap.put("street", tradeAreaLevel.replace("_", "-"));
                zoomMap.put("district", streetLevel.replace("_", "-"));
                zoomMap.put("city", funcAreaLevel.replace("_", "-"));
            }
        }catch(Exception e){
            log.error("getFuncAreaZoom:",e);
        }
        return zoomMap;
    }
}
